home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / dev / sun4c.md / devSCSIC90Mach.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-12-19  |  9.8 KB  |  370 lines

  1.  /* 
  2.  * devSCSIC90Mach.c --
  3.  *
  4.  *    Routines specific to the SCSI NCR 53C9X Host Adaptor which
  5.  *    depend on the machine architecture.
  6.  *
  7.  * Copyright 1991 Regents of the University of California
  8.  * Permission to use, copy, modify, and distribute this
  9.  * software and its documentation for any purpose and without
  10.  * fee is hereby granted, provided that the above copyright
  11.  * notice appear in all copies.  The University of California
  12.  * makes no representations about the suitability of this
  13.  * software for any purpose.  It is provided "as is" without
  14.  * express or implied warranty.
  15.  */
  16.  
  17. #ifndef lint
  18. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/dev/sun4c.md/devSCSIC90Mach.c,v 1.3 91/10/18 01:19:44 dlong Exp $ SPRITE (Berkeley)";
  19. #endif /* not lint */
  20.  
  21. #include "sprite.h"
  22. #include "devAddrs.h"
  23. #include "scsiC90.h"
  24. #include "mach.h"
  25. #include "machMon.h"
  26. #include "dev.h"
  27. #include "devInt.h"
  28. #include "scsiHBA.h"
  29. #include "scsiDevice.h"
  30. #include "sync.h"
  31. #include "stdio.h"
  32. #include "stdlib.h"
  33. #include "string.h"
  34. #include "devSCSIC90.h"
  35. #include "devSCSIC90Int.h"
  36.  
  37. extern Boolean DevEntryAvailProc();
  38. /*
  39.  * Forward declarations.  
  40.  */
  41.  
  42. static Boolean          ProbeSCSI _ARGS_ ((int address));
  43.  
  44. volatile DMARegs    *dmaRegsPtr = (volatile DMARegs *) NIL;
  45. int    dmaControllerActive = 0;
  46.  
  47. static int scsiInitiatorID = 7;
  48.  
  49.  
  50. /*
  51.  *----------------------------------------------------------------------
  52.  *
  53.  * ProbeSCSI --
  54.  *
  55.  *    Test for the existence for the interface.
  56.  *
  57.  * Results:
  58.  *    TRUE if the host adaptor was found.
  59.  *
  60.  * Side effects:
  61.  *    None.
  62.  *
  63.  *----------------------------------------------------------------------
  64.  */
  65. static Boolean
  66. ProbeSCSI(address)
  67.     int address;            /* Alledged controller address */
  68. {
  69.     ReturnStatus    status;
  70.     volatile CtrlRegs    *regsPtr = (volatile CtrlRegs *) address;
  71.     int            x;
  72.  
  73.     /*
  74.      * Touch the device's status register.  Should I read something else?
  75.      */
  76.     status = Mach_Probe(sizeof (regsPtr->scsi_ctrl.read.status),
  77.         (Address) &(regsPtr->scsi_ctrl.read.status), (Address) &x);
  78.     if (status != SUCCESS) {
  79.     if (devSCSIC90Debug > 3) {
  80.         printf("SCSIC90 not found at address 0x%x\n",address);
  81.     }
  82.         return (FALSE);
  83.     }
  84.     if (devSCSIC90Debug > 3) {
  85.     printf("SCSIC90 found\n");
  86.     }
  87.     return(TRUE);
  88. }
  89.  
  90. /*
  91.  *----------------------------------------------------------------------
  92.  *
  93.  * DevReset --
  94.  *
  95.  *    Reset a SCSI bus controlled by the SCSI-3 Sun Host Adaptor.
  96.  *
  97.  * Results:
  98.  *    None.
  99.  *
  100.  * Side effects:
  101.  *    Reset the controller and SCSI bus.
  102.  *
  103.  *----------------------------------------------------------------------
  104.  */
  105. void
  106. DevReset(ctrlPtr)
  107.     Controller *ctrlPtr;
  108. {
  109.     volatile CtrlRegs *regsPtr = (volatile CtrlRegs *)ctrlPtr->regsPtr;
  110.     Device *devPtr;
  111.     int i,j;
  112.  
  113.     /* Reset scsi controller. */
  114.     regsPtr->scsi_ctrl.write.command = CR_RESET_CHIP;
  115.     MACH_DELAY(200);
  116.     regsPtr->scsi_ctrl.write.command = CR_DMA | CR_NOP;
  117.     MACH_DELAY(200);
  118.     dmaControllerActive = 0;        /* Allow dma reset to happen. */
  119.     Dev_ScsiResetDMA();
  120.     MACH_DELAY(200);
  121.  
  122.     regsPtr->scsi_ctrl.write.config1 |= C1_REPORT | scsiInitiatorID;
  123.     MACH_DELAY(200);
  124.     regsPtr->scsi_ctrl.write.command = CR_RESET_BUS;
  125.     MACH_DELAY(800);
  126.     for (i=0; i<8; i++) {
  127.     for (j=0; j<8; j++) {
  128.         devPtr = ctrlPtr->devicePtr[i][j];
  129.         if ((devPtr != (Device *)NIL) && (devPtr != (Device *)0)) {
  130.         devPtr->synchPeriod = 0;
  131.         devPtr->synchOffset = 0;
  132.         }
  133.     }
  134.     }
  135.     /*
  136.      * We initialize configuration, clock conv, synch offset, etc, in
  137.      * SendCommand.
  138.      * Parity is disabled by hardware reset or software.
  139.      */
  140.  
  141.     return;
  142. }
  143.  
  144.  
  145. /*
  146.  *----------------------------------------------------------------------
  147.  *
  148.  * Dev_ScsiResetDMA --
  149.  *
  150.  *    Reset the DMA controller.  The SCSI module owns the dma controller,
  151.  *    so it gets to decide when it may be reset or not.  The network
  152.  *    module also calls us to try to reset it.
  153.  *
  154.  * Results:
  155.  *    None.
  156.  *
  157.  * Side effects:
  158.  *    DMA chip reset.
  159.  *
  160.  *----------------------------------------------------------------------
  161.  */
  162. void
  163. Dev_ScsiResetDMA()
  164. {
  165.     static    int    whichTime = 0;
  166.  
  167.     if (whichTime > 1) {
  168.     return;
  169.     }
  170.  
  171.     whichTime++;
  172.  
  173.     if (dmaControllerActive > 0 && devSCSIC90Debug > 4) {
  174.     printf("Wanted to reset dma controller, but it was active: %d\n",
  175.         dmaControllerActive);
  176.     return;
  177.     }
  178.     if (dmaRegsPtr == (DMARegs *) NIL) { 
  179.     if (Mach_MonSearchProm("dma", "address", (char *)&dmaRegsPtr,
  180.         sizeof dmaRegsPtr) != sizeof dmaRegsPtr) {
  181.             MachDevReg reg;
  182.         Address phys;
  183.  
  184.         Mach_MonSearchProm("dma", "reg", (char *)®, sizeof reg);
  185.         if (romVectorPtr->v_romvec_version < 2
  186.             && reg.addr >= (Address)SBUS_BASE
  187.             && reg.bustype == 1) {          /* old style */
  188.         phys = reg.addr;
  189.         } else {                                /* new style */
  190.         phys = reg.addr + SBUS_BASE +
  191.                reg.bustype * SBUS_SIZE;
  192.         }
  193.         dmaRegsPtr = (DMARegs *) VmMach_MapInDevice(phys, 1);
  194.     }
  195.     }
  196.  
  197.     /* Reset dma controller. */
  198.     dmaRegsPtr->ctrl = DMA_RESET;
  199.     MACH_DELAY(200);
  200.     /* Reset the dma reset bit. */
  201.     dmaRegsPtr->ctrl = dmaRegsPtr->ctrl & ~(DMA_RESET);
  202.     /* Allow dma interrupts. */
  203.     dmaRegsPtr->ctrl = DMA_INT_EN;
  204.     MACH_DELAY(200);
  205.  
  206.     if (devSCSIC90Debug > 4) {
  207.     printf("Returning from Reset command.\n");
  208.     }
  209.  
  210.     return;
  211. }
  212.  
  213.  
  214. /*
  215.  *----------------------------------------------------------------------
  216.  *
  217.  * DevStartDMA --
  218.  *
  219.  *    Issue the sequence of commands to the controller to start DMA.
  220.  *    This can be called by Dev_SCSIC90Intr in response to a DATA_{IN,OUT}
  221.  *    phase message.
  222.  *
  223.  * Results:
  224.  *    None.
  225.  *
  226.  * Side effects:
  227.  *    DMA is enabled.  No registers other than the control register are
  228.  *    to be accessed until DMA is disabled again.
  229.  *
  230.  *----------------------------------------------------------------------
  231.  */
  232. void
  233. DevStartDMA(ctrlPtr)
  234.     Controller *ctrlPtr;
  235. {
  236.     volatile CtrlRegs    *regsPtr;
  237.     int            size;
  238.     Device              *devPtr = ctrlPtr->devPtr;
  239.     Address             buffer;
  240.  
  241.     size = devPtr->activeBufLen;
  242.     buffer = devPtr->activeBufPtr;
  243.  
  244.     if (devSCSIC90Debug > 4) {
  245.     printf("StartDMA called for %s, dma %s, size = %d.\n", ctrlPtr->name,
  246.         (devPtr->dmaState == DMA_RECEIVE) ? "receive" :
  247.         ((devPtr->dmaState == DMA_SEND) ? "send" :
  248.                           "not-active!"), size);
  249.     }
  250.     if (devPtr->dmaState == DMA_INACTIVE) {
  251.     printf("StartDMA: Returning, since DMA state isn't active.\n");
  252.     return;
  253.     }
  254.     regsPtr = ctrlPtr->regsPtr;
  255.     /*
  256.      * A DMA cannot cross a 16Mbyte boundary using this dma controller.
  257.      * We could remap pages if it does, but since the file system won't
  258.      * do this, we just panic for now.
  259.      */
  260.     if (((unsigned) buffer & 0xff000000) !=
  261.         (((unsigned) buffer + size - 1) & 0xff000000)) {
  262.     panic("DMA crosses 16Mbyte boundary.\n");
  263.     }
  264.     if (buffer == (Address) NIL) {
  265.     panic("DMA buffer was NIL before dma.\n");
  266.     }
  267.     dmaRegsPtr->addr = (unsigned int) buffer;
  268.  
  269.     /*
  270.      * Put transfer size in counter.  If this is 16k (max size), this puts
  271.      * a 0 in the counter, which is the correct thing to do.
  272.      */
  273.     /* High byte of size. */
  274.     regsPtr->scsi_ctrl.write.xCntHi = (unsigned char) ((size & 0xff00) >> 8);
  275.     /* Low byte of size. */
  276.     regsPtr->scsi_ctrl.write.xCntLo = (unsigned char) (size & 0x00ff);
  277.     /* Load count into counter by writing a DMA NOP command on C90 only */
  278.     regsPtr->scsi_ctrl.write.command = CR_DMA | CR_NOP;
  279.     /* Enable DMA */
  280.     if (devPtr->dmaState == DMA_RECEIVE) {
  281.     dmaRegsPtr->ctrl = DMA_EN_DMA | DMA_READ | DMA_INT_EN;
  282.     } else {
  283.     dmaRegsPtr->ctrl = DMA_EN_DMA | DMA_INT_EN;
  284.     }
  285.     /* Start scsi command. */
  286.     regsPtr->scsi_ctrl.write.command = CR_DMA | CR_XFER_INFO;
  287.  
  288.     return;
  289. }
  290.  
  291.  
  292. /*
  293.  *----------------------------------------------------------------------
  294.  *
  295.  * DevSCSIC90Init --
  296.  *
  297.  *    Check for the existant of the Sun SCSIC90 HBA controller. If it
  298.  *    exists allocate data stuctures for it.
  299.  *
  300.  * Results:
  301.  *    TRUE if the controller exists, FALSE otherwise.
  302.  *
  303.  * Side effects:
  304.  *    Memory may be allocated.
  305.  *
  306.  *----------------------------------------------------------------------
  307.  */
  308. ClientData
  309. DevSCSIC90Init(ctrlLocPtr)
  310.     DevConfigController    *ctrlLocPtr;    /* Controller location. */
  311. {
  312.     int    ctrlNum;
  313.     Boolean    found;
  314.     Controller *ctrlPtr;
  315.     int    i,j;
  316.     static int numSCSIC90Controllers = 0; /* highest controller we've
  317.                        * probed for */
  318.  
  319.     /*
  320.      * See if the controller is there. 
  321.      */
  322.     ctrlNum = ctrlLocPtr->controllerID;
  323.     found =  ProbeSCSI(ctrlLocPtr->address);
  324.     if (!found) {
  325.     return DEV_NO_CONTROLLER;
  326.     }
  327.     if (Mach_MonSearchProm("options", "scsi-initiator-id",
  328.     (char *)&scsiInitiatorID, sizeof(int)) != sizeof(int)) {
  329.     scsiInitiatorID = 7;
  330.     }
  331.  
  332.  
  333.     /*
  334.      * It's there. Allocate and fill in the Controller structure.
  335.      */
  336.     if (ctrlNum+1 > numSCSIC90Controllers) {
  337.     numSCSIC90Controllers = ctrlNum+1;
  338.     }
  339.     Controllers[ctrlNum] = ctrlPtr = (Controller *) malloc(sizeof(Controller));
  340.     bzero((char *) ctrlPtr, sizeof(Controller));
  341.     ctrlPtr->regsPtr = (volatile CtrlRegs *) (ctrlLocPtr->address);
  342.     ctrlPtr->name = ctrlLocPtr->name;
  343.     Sync_SemInitDynamic(&(ctrlPtr->mutex), ctrlPtr->name);
  344.     /* 
  345.      * Initialized the name, device queue header, and the master lock.
  346.      * The controller comes up with no devices active and no devices
  347.      * attached.  Reserved the devices associated with the 
  348.      * targetID of the controller (7).
  349.      */
  350.     ctrlPtr->devPtr = (Device *)NIL;
  351.     ctrlPtr->interruptDevPtr = (Device *)NIL;
  352.     ctrlPtr->devQueuesMask = 0;
  353.     ctrlPtr->devQueues = Dev_CtrlQueuesCreate(&(ctrlPtr->mutex),
  354.                           DevEntryAvailProc);
  355.     for (i = 0; i < 8; i++) {
  356.     for (j = 0; j < 8; j++) {
  357.         ctrlPtr->devicePtr[i][j] =
  358.         (i == 7) ? (Device *) 0 : (Device *) NIL;
  359.     }
  360.     }
  361.     Controllers[ctrlNum] = ctrlPtr;
  362.     DevReset(ctrlPtr);
  363.  
  364.     if (devSCSIC90Debug > 3) {
  365.     printf("devSCSIC90Init: controller 0x%02x initialized.\n", ctrlNum);
  366.     }
  367.  
  368.     return (ClientData) ctrlPtr;
  369. }
  370.